From: Julien Grall Date: Thu, 14 Nov 2013 17:00:34 +0000 (+0000) Subject: xen/arm: p2m: flush TLB by VMID when a new domain is creating X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~5926 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success/%22http:/www.example.com/cgi/success?a=commitdiff_plain;h=80ede1ac29b9207b274c85d2b91201d8c4db55ec;p=xen.git xen/arm: p2m: flush TLB by VMID when a new domain is creating Once the VMID is marked unused, a new domain can reuse the VMID for its own. If the TLB is not flushed, entries can contain wrong translation. When a new p2m is allocated, switch to the new VMID and flush TLB on every physical CPUs. Signed-off-by: Julien Grall Acked-by: Stefano Stabellini Acked-by: Ian Campbell --- diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 2d09fef5d6..82dda652c5 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -302,6 +302,15 @@ int p2m_alloc_table(struct domain *d) d->arch.vttbr = page_to_maddr(p2m->first_level) | ((uint64_t)p2m->vmid&0xff)<<48; + p2m_load_VTTBR(d); + + /* Make sure that all TLBs corresponding to the new VMID are flushed + * before using it + */ + flush_tlb(); + + p2m_load_VTTBR(current->domain); + spin_unlock(&p2m->lock); return 0; @@ -357,6 +366,7 @@ static void p2m_free_vmid(struct domain *d) spin_lock(&vmid_alloc_lock); if ( p2m->vmid != INVALID_VMID ) clear_bit(p2m->vmid, vmid_mask); + spin_unlock(&vmid_alloc_lock); } diff --git a/xen/include/asm-arm/arm32/flushtlb.h b/xen/include/asm-arm/arm32/flushtlb.h index a258f58daa..ab166f39a5 100644 --- a/xen/include/asm-arm/arm32/flushtlb.h +++ b/xen/include/asm-arm/arm32/flushtlb.h @@ -12,6 +12,17 @@ static inline void flush_tlb_local(void) isb(); } +/* Flush inner shareable TLBs, current VMID only */ +static inline void flush_tlb(void) +{ + dsb(); + + WRITE_CP32((uint32_t) 0, TLBIALLIS); + + dsb(); + isb(); +} + /* Flush local TLBs, all VMIDs, non-hypervisor mode */ static inline void flush_tlb_all_local(void) { diff --git a/xen/include/asm-arm/arm64/flushtlb.h b/xen/include/asm-arm/arm64/flushtlb.h index d0535a06bb..9ce79a86c3 100644 --- a/xen/include/asm-arm/arm64/flushtlb.h +++ b/xen/include/asm-arm/arm64/flushtlb.h @@ -12,6 +12,17 @@ static inline void flush_tlb_local(void) : : : "memory"); } +/* Flush innershareable TLBs, current VMID only */ +static inline void flush_tlb(void) +{ + asm volatile( + "dsb sy;" + "tlbi vmalle1is;" + "dsb sy;" + "isb;" + : : : "memory"); +} + /* Flush local TLBs, all VMIDs, non-hypervisor mode */ static inline void flush_tlb_all_local(void) {